/* BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER.   
 * 
 * This file only supports UART 1
 */

/* Standard includes. */
//#include <msp430x14x.h>

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "constants.h"
#include "queue.h"
#include "task.h"
#include "serial.h"

#include "uart.h"


/* The queues used to hold received characters. */
static xQueueHandle xRxedHeart; 
static xQueueHandle xRxedData;

static volatile short sTHREEmpty;

/*-----------------------------------------------------------*/
xComPortHandle xSerialPortInitCustom( unsigned portBASE_TYPE uxQueueLength )
{
	/* Initialise the hardware. */
	portENTER_CRITICAL();
	{
		/* Create the queues used by the sending tasks. */
		xRxedHeart = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
                xRxedData = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );

		/************************************
                              Init UART
                 ***********************************/

		/* Nothing in the buffer yet. */
	}
	portEXIT_CRITICAL();
	
	return NULL;
}
/*-----------------------------------------------------------*/

signed portBASE_TYPE xSerialGetHeartPkt( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime )
{
    int i, bytesRxed=0;
    /* Get the next character from the buffer.  Return false if no characters
    are available, or arrive before xBlockTime expires. */

    // Grab Semaphore/Mutex for using the queue here

    for(i=0; i<PKT_SIZE; i++){
        if( xQueueReceive( xRxedHeart, &pcRxedChar[i], xBlockTime ) ){
		bytesRxed++;
	} else {
                break;
	}
    }

    // Release Semaphore/Mutex for using the queue here

    if(bytesRxed<MIN_RX_PKT_SIZE){
      return pdFALSE;
    } else {
      return pdTRUE;
    }
}

signed portBASE_TYPE xSerialGetDataPkt( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime )
{
    int i, bytesRxed=0;
    /* Get the next character from the buffer.  Return false if no characters
    are available, or arrive before xBlockTime expires. */

    // Grab Semaphore/Mutex for using the queue here

    for(i=0; i<PKT_SIZE; i++){
        if( xQueueReceive( xRxedData, &pcRxedChar[i], xBlockTime ) ){
		bytesRxed++;
	} else {
                break;
	}
    }

    // Release Semaphore/Mutex for using the queue here

    if(bytesRxed<MIN_RX_PKT_SIZE){
      return pdFALSE;
    } else {
      return pdTRUE;
    }
}
/*-----------------------------------------------------------*/

/*
* UART RX interrupt service routine.
*/
  void vRxISR( void ) __interrupt[ UART1RX_VECTOR ]
  {
      signed char *cChar;
      int i;
      portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
      portBASE_TYPE xNonGamePkt = pdTRUE;
      
      /* Get the character from the UART and post it on the queue of Rxed 
      characters. */
      
      //ccRX(/*cChar*/);
      
      if(cChar[3] == 'G' || cChar[3] == 'B'){
        xNonGamePkt = pdFALSE;
      }

      for(i=0; i<sizeof(cChar); i++){
        if(xNonGamePkt == pdTRUE){
          xQueueSendFromISR( xRxedHeart, &cChar[i], &xHigherPriorityTaskWoken );  // place on the heart beat queue
        } else {
          xQueueSendFromISR( xRxedData, &cChar[i], &xHigherPriorityTaskWoken );  // place on the game guess queue
        }
      }
      
      if( xHigherPriorityTaskWoken )
      {
              /*If the post causes a task to wake force a context switch 
              as the woken task may have a higher priority than the task we have 
              interrupted. */
              taskYIELD();
      }
      
      /* Make sure any low power mode bits are clear before leaving the ISR. */
      __bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
  }
  /*-----------------------------------------------------------*/

